package cn.tede.submarine;
import javax.swing.JFrame;//画窗口第 1 步
import javax.swing.JPanel;
import java.awt.*;
import java.util.Arrays;
import java.util.Timer;//做定时器用
import java.util.TimerTask;//做定时器用
import java.util.Random;
import java.awt.event.KeyAdapter;//做触发用，不需要掌握
import java.awt.event.KeyEvent;//做触发用，不需要掌握


/** 整个游戏世界 */
public class World extends JPanel{//画窗口第 2 步
    public static final int WIDTH = 641;        //窗口的宽
    public static final int HEIGHT = 479;       //窗口的高

    public static final int RUNNING = 0;//运行状态
    public static final int GAME_OVER = 1;//游戏结束状态
    private int state = RUNNING;//当前状态默认 为运行状态

    private Battleship ship = new Battleship();//放在main()外面充当成员变量，全局都能用
    private SeaObject[] submarines = {};//潜艇数组
    private Mine[] mines = {};//水雷数组
    private Bomb[] bombs = {};//深水炸弹数组

    public SeaObject nextSubmarine(){
        Random rand = new Random();
        int type = rand.nextInt(20);//0-19之间的随机数
        if (type<10){
            return new ObserveSubmarine();
        }else if (type<15){
            return new TorpedoSubmarine();
        }else {
            return new MineSubmarine();
        }
    }
    private int subEnterIndex = 0;
    public void submarineEnterAction(){//每10个ms走一次（1s=1000ms）
        subEnterIndex++;
        if (subEnterIndex%40==0){
            //每10*40ms走一次
            //获取潜艇对象
            SeaObject obj = nextSubmarine();
            submarines = Arrays.copyOf(submarines,submarines.length+1);
            submarines[submarines.length-1] = obj;
        }
    }

    //水雷入场
    private int mineEnterIndex = 0;
    public void mineEnterAction(){
        //每10ms走一次（run里都是如此）
        mineEnterIndex++;
        if (mineEnterIndex%100==0){
            //10*100=1000ms=1s走一次
            //每一个水雷潜艇都要发射炸弹
            for (int i=0;i<submarines.length;i++) {
                // 强转了下面(想干的事超类里没有，谁有就想转成谁)
                if (submarines[i] instanceof MineSubmarine){
                    //若潜艇是水雷艇类型,将潜艇强转为水雷艇类型
                    MineSubmarine ms = (MineSubmarine)submarines[i];
                    Mine obj = ms.shootMine();//获取水雷对象
                    mines = Arrays.copyOf(mines, mines.length + 1);
                    mines[mines.length - 1] = obj;

                }
            }

        }
    }
    //海洋对象移动
    public void moveAction(){
        //10ms走一次
        for(int i=0;i<submarines.length;i++){
            submarines[i].move();//遍历所有潜艇并让每个潜艇都动
        }
        for (int i=0;i<mines.length;i++){
            mines[i].move();//水雷移动
        }
        for (int i=0;i<bombs.length;i++){
            bombs[i].move();//深水炸弹移动
        }

    }

    public void outOfBoundsAction(){
        //删除越界的海洋对象
        for(int i=0;i<submarines.length;i++){
            if (submarines[i].isOutOfBounds() || submarines[i].isDead()){//越界了或者给炸死了
                submarines[i] = submarines[submarines.length-1];
                submarines = Arrays.copyOf(submarines,submarines.length-1);
            }
        }
        for (int i=0;i<mines.length;i++){
            //水雷缩容
            if (mines[i].isOutOfBounds() || mines[i].isDead()){
                mines[i] = mines[mines.length-1];
                mines = Arrays.copyOf(mines,mines.length-1);
            }
        }
        for (int i=0;i<bombs.length;i++){
            if (bombs[i].isOutOfBounds() || bombs[i].isDead()){ //越界了或者给炸死了
                bombs[i] = bombs[bombs.length-1];
                bombs = Arrays.copyOf(bombs,bombs.length-1);
            }
        }
    }

    private int score;
    public void bombBangAction(){
        //每10ms走一次
        for (int i=0;i<bombs.length;i++){
            Bomb b = bombs[i];
            for (int j=0;j<submarines.length;j++){
                SeaObject s = submarines[j];
                if (b.isLive() && s.isLive() && s.isHit(b)){//若都或者并且还撞上了
                    s.goDead();
                    b.goDead();
                    if (s instanceof EnemyScore){//若被撞对象是分
                        EnemyScore es = (EnemyScore)s;//将被撞对象强转为得分接口
                        score += es.getScore();//玩家得分
                    }
                    if (s instanceof EnemyLife){//若被撞对象是命
                        EnemyLife ea = (EnemyLife)s;//将被撞对象强转为得命接口
                        int num = ea.getLife();//获得命数
                        ship.addLife(num);//战舰增命
                    }

                }
            }
        }
    }

    //水雷与战舰的碰撞
    public void mineBangAction(){
        for (int i=0;i<mines.length;i++){
            Mine m = mines[i];
            if (m.isLive() && ship.isLive() && m.isHit(ship)){
                m.goDead();
                ship.subtractLife();//战舰减一条命
            }
        }
    }

    //检测游戏结束
    public void checkGameOverAction(){
        if (ship.getLife()<=0){
            //若战舰命数<=0表示游戏结束
            state = GAME_OVER;
        }
    }
    //启动程序执行
    public void action(){
        /* 不需要掌握，监听键盘的 */
        KeyAdapter k = new KeyAdapter() {
            //重写keyReleased()方法
            public void keyReleased(KeyEvent e) {
                //当按键抬起时会自动触发
                if (e.getKeyCode()== KeyEvent.VK_SPACE){
                    //若按下的是空格键
                    Bomb obj = ship.shoot();
                    bombs = Arrays.copyOf(bombs,bombs.length+1);
                    bombs[bombs.length-1] = obj;
                }
                if (e.getKeyCode()==KeyEvent.VK_LEFT){
                    //若抬起左键头
                    ship.moveLeft();//战舰左移
                }
                if (e.getKeyCode()==KeyEvent.VK_RIGHT){
                    ship.moveRight();
                }
            }
        };
        this.addKeyListener(k);

        Timer timer = new Timer();//定时器对象
        int interval = 10;//定时间隔(以毫秒为单位)
        timer.schedule(new TimerTask() {
            public void run() {
                //定时做的事（每10ms自动发生）
                submarineEnterAction();//表示潜艇（三种）入场
                mineEnterAction();//水雷入场
                moveAction();
                outOfBoundsAction();
                bombBangAction();
                mineBangAction();
                checkGameOverAction();
                repaint();//重画进去
            }
        }, interval, interval);//定时计划

    }


    //重写paint()画
    public void paint(Graphics g){
        //不同状态下画不同的图
        //这个方法不要纠结

        switch (state){
            case GAME_OVER:
                Images.gameover.paintIcon(null,g,0,0);
                break;
            case RUNNING:
                Images.sea.paintIcon(null,g,0,0);//海洋图
                ship.paintImage(g);
                for (int i=0;i<submarines.length;i++){
                    submarines[i].paintImage(g);
                }
                for (int i=0;i<bombs.length;i++){
                    bombs[i].paintImage(g);
                }
                for (int i=0;i<mines.length;i++){
                    mines[i].paintImage(g);
                }
                g.drawString("SCORE："+score,200,50);//画分，不要求掌握
                g.drawString("LIFE："+ship.getLife(),400,50);//画分，不要求掌握
        }


    }
    //做窗口
    public static void main(String[] args) {
        //画窗口第 3 步
        JFrame frame = new JFrame();
        World world = new World();
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH+16,HEIGHT+39);//多了最小化、最大化、关闭的窗口
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);//1)设置窗口可见   2).系统尽快调用paint方法

        world.action();//启动程序的执行

    }

}
